package cn.demoframe.test.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.net.www.protocol.http.HttpURLConnection;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.List;
import java.util.Map;

public class HttpclientUtils {
    private static final Logger logger = LoggerFactory.getLogger(Thread
            .currentThread().getStackTrace()[1].getClassName());

    public HttpclientUtils(){
        bulider = RequestConfig.custom();
        this.setHttpSo_Timeout(40000);
        this.setHttpConnection_Timeout(40000);
        initConfig();
        httpclient = HttpClients.createDefault();
    }
    private final String UTF8 = "UTF-8";
    private String Encoding = UTF8;
    private CloseableHttpClient httpclient;
    private RequestConfig requestConfig;
    private RequestConfig.Builder bulider;

    public void setEncodingUTF8(){
        Encoding = UTF8;
    }

    public void setEncodingGBK(){
        Encoding = "GBK";
    }

    /**
     * 设置http服务器连接超时
     * */
    public void setHttpConnection_Timeout(int timeout) {
        bulider.setConnectTimeout(timeout);
        initConfig();
    }

    /**
     * 设置http服务器响应超时
     * */
    public void setHttpSo_Timeout(int timeout) {
        bulider.setSocketTimeout(timeout);
        initConfig();
    }

    private void initConfig() {
        requestConfig = bulider.build();
    }

    /**
     * Http访问，Get方法
     * @param url 请求地址
     * @return 请求结果
     */
	public String httpGet(String url) {
        // 返回网页body
    	String body = "";
        CloseableHttpResponse response = null;
        try{
            // 目标地址
            HttpGet httpget = new HttpGet(url);
            httpget.setConfig(requestConfig);
            // 执行
            response = httpclient.execute(httpget);

            logger.debug("---------------返回结果-----------------");
            logger.debug("" + response.getStatusLine());
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 显示结果
                body = EntityUtils.toString(response.getEntity(), Encoding);
            } else if(response.getStatusLine().getStatusCode() == HttpStatus.SC_GATEWAY_TIMEOUT) {
                logger.error("httpPost网关超时.");
                body = Constants.HTTP_TIMEOUT_STR;
            }
            logger.debug(body);
        } catch (ConnectTimeoutException e) {
            logger.error("httpGet连接超时.", e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (SocketTimeoutException e) {
            logger.error("httpGet响应超时.",e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (IOException e){
            logger.error("httpGet失败.",e);
        } finally {
            if(response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

    /**
     * Http访问，Post方法
     * @param url 请求地址
     * @param params 参数
     * @return 结果
     */
	public String httpPost(String url, List<NameValuePair> params) {
        // 返回网页body
    	String body = "";
        CloseableHttpResponse response = null;
        try{
            // 目标地址
            HttpPost httppost = new HttpPost(url);
            httppost.setConfig(requestConfig);
            // 设置参数
            httppost.setEntity(new UrlEncodedFormEntity(params, Encoding));
            // 执行
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            logger.debug("---------------返回结果-----------------");
            logger.debug("" + response.getStatusLine());
            if (entity != null) {
                logger.debug("Response content length: " + entity.getContentLength());
                // 显示结果
                body = EntityUtils.toString(entity, Encoding);
            }
        } catch (ConnectTimeoutException e) {
            logger.error("httpPost连接超时.", e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (SocketTimeoutException e) {
            logger.error("httpPost响应超时.",e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (IOException e){
            logger.error("httpPost失败.",e);
        } finally {
            if(response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

    /**
     * post请求
     * @param url 请求地址
     * @param param 请求参数
     * @return 请求结果
     */
	public String httpPost(String url, String param) {
        // 返回网页body
		String body = "";
        CloseableHttpResponse response = null;
        try{
            // 目标地址
            HttpPost httppost = new HttpPost(url);
            httppost.setConfig(requestConfig);
            // 设置类型
            StringEntity se = new StringEntity(param, Encoding);
    		se.setContentType("application/x-www-form-urlencoded");
            System.out.println(param);
            // 设置参数
            httppost.setEntity(se);
            // 执行
            response = httpclient.execute(httppost);
            logger.debug("---------------返回结果-----------------");
            logger.debug("" + response.getStatusLine());
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 显示结果
                body = EntityUtils.toString(response.getEntity());
            } else if(response.getStatusLine().getStatusCode() == HttpStatus.SC_GATEWAY_TIMEOUT) {
                logger.error("httpPost网关超时.");
                body = Constants.HTTP_TIMEOUT_STR;
            }
            logger.debug(body);
        } catch (ConnectTimeoutException e) {
            logger.error("httpPost连接超时.", e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (SocketTimeoutException e) {
            logger.error("httpPost响应超时.",e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (IOException e){
            logger.error("httpPost失败.",e);
        } finally {
            if(response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

	/**
     * 发送soap协议
     * @param postUrl soap的wsdl地址
     * @param content soap的具体内容，编辑soapUI发送的xml内容
     * @param soapAction soapAction对应的url
     * @return 结果
     * @throws IOException 异常
     */
    public String postSoap(String postUrl, String content, String soapAction) throws IOException {
        // Post请求的url，与get不同的是不需要带参数
        URL url = new URL(postUrl);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();

        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("POST");
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setRequestProperty("Content-Type", "text/xml; charset=" + Encoding);
        connection.setRequestProperty("SOAPAction", soapAction);

        StringBuilder result = new StringBuilder();
        BufferedReader reader = null;
        try {
        	connection.connect();
            DataOutputStream out = new DataOutputStream(connection
                    .getOutputStream());
            out.write(content.getBytes(Encoding));

            out.flush();
            out.close(); // flush and close
            reader = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
            	result.append(line);
            }
		} catch (Exception e) {
			logger.error("soap error: ", e);
		} finally {
			 reader.close();
		     connection.disconnect();
		}

        return result.toString();
    }

    /**
     * 解析请求参数
     * @param request 请求
     * @return 结果
     */
    public static String getPostBody(HttpServletRequest request){
        String method = request.getMethod();

        if (!method.equalsIgnoreCase("POST")) {
            logger.debug("IS NOT POST REQUEST METHOD!={}", method);
            return null;
        }

        String httpBody = null;
        BufferedReader reader = null;
		try {
			reader = request.getReader();
			StringBuilder sb = new StringBuilder();
            String line;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
			httpBody = sb.toString();
		} catch (IOException e) {
			logger.error("解析请求参数异常", e);
		}

        logger.debug("http body={}", httpBody);
        request.setAttribute("httpBody", httpBody);
        return httpBody;
    }

    /**
     * post 请求，json格式
     * @param url 地址
     * @param se 参数
     * @return 结果
     */
    public String httpPostJson(String url, StringEntity se, Map<String, String> headerMap) {
        // 返回网页body
		String body = "";
        CloseableHttpResponse response = null;
        try{
            // 目标地址
            HttpPost httppost = new HttpPost(url);
            httppost.setConfig(requestConfig);
            // 设置类型
    		se.setContentType("application/json");
    		se.setContentEncoding("UTF-8");
            // 设置参数
            httppost.setEntity(se);
            if(headerMap != null && headerMap.size() > 0) {
            	for (String key : headerMap.keySet()) {
            		httppost.setHeader(key, headerMap.get(key));
            	}
            }
            // 执行
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            logger.debug("---------------返回结果-----------------");
            logger.debug("" + response.getStatusLine());
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 显示结果
                body = EntityUtils.toString(entity);
            } else if(response.getStatusLine().getStatusCode() == HttpStatus.SC_GATEWAY_TIMEOUT) {
                logger.error("httpPost网关超时.");
                body = Constants.HTTP_TIMEOUT_STR;
            }
        } catch (ConnectTimeoutException e) {
            logger.error("httpPost连接超时.", e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (SocketTimeoutException e) {
            logger.error("httpPost响应超时.",e);
            body = Constants.HTTP_TIMEOUT_STR;
        } catch (IOException e){
            logger.error("httpPost失败.",e);
        } finally {
            if(response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

}
